/*
 * @Author: zhaoxiangyu@
 * @Date: 2021-11-05 09:34:46
 * @LastEditors: 647355931@qq.com
 * @LastEditTime: 2021-11-06 15:00:05
 * @Description: file content
 */
// 拦截数据
// target 要拦截的对象
// key 要拦截的key

import Dep from "./dep.js";
import observe from "./observe.js";

// val 要拦截的值
export default function defineReactive(target, key, val) {
  // 如果 val 是个对象那么就先处理内部的
  const childOb = observe(val);
  console.log("childOb ===> ", childOb);
  // 收集依赖 (谁用了我 我就收集谁 下次更新的时候就更新这个依赖项)
  const dep = new Dep();
  // 如果是单独的值 就直接设置
  Object.defineProperty(target, key, {
    get() {
      // 如果 Dep.target 有值 表示已经被实例化  可以手机依赖
      // 当前的dep依赖收集只会收集一层
      //  { key: value }

      // 但是当key 对应的是一个object 那么就无法触发依赖收集
      //  { key: { son: 1, bon: 2 } }
      console.log('Dep.target ====> 33333333333333333', Dep.target);

      if (Dep.target) {
        // console.log("dep===>", dep);
        dep.depend();
        // 如果存在子  ob 就把子对象的依赖收集了
        if (childOb) {
          childOb.dep.depend();
        }
      }
      // 当调用  this.xxx 的时候 会去收集依赖
      // console.warn(`调用了${key} 值为${val}`);
      // console.log("dep+===> ", dep);
      return val;
    },
    set(newV) {
      console.warn(`修改了${key} 值为${val}`);
      if (newV === val) return;
      val = newV;
      // 赋值 如果赋值得 是一个新的对象 { a: 'aaa'}
      // 那么需要为这个新值做响应式拦截和处理
      observe(newV);
      // 修改完毕后 通知dom 修改
      // console.log("dep+===> ", dep);
      dep.notify();
    },
  });
}

// 为数组添加一个不存在的属性 并且设置响应式
function set(target, key, val) {
  // 如果target中本来就存在key 那么就替换
  if (target[key]) {
    console.warn(`${key} 已存在 直接修改为${val}`);
    target[key] = val;
  } else {
    console.warn(`${key} 不存在 添加并设置值为${val}`);
    defineReactive(target, key, val);
  }
}